using Lzfy_His_Service.Models;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Senparc.Weixin.Work.AdvancedAPIs;
using Senparc.Weixin.Work.AdvancedAPIs.OAuth2;
using Senparc.Weixin.Work.Containers;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Data;
using Microsoft.Data.SqlClient;
using Dapper;
using Microsoft.Extensions.Logging;

namespace Lzfy_His_Service.Services
{
    /// <summary>
    /// 企业微信服务实现
    /// </summary>
    public class WeChatWorkService : IWeChatWorkService
    {
        private readonly WeChatWorkConfig _config;
        private readonly IConfiguration _configuration;
        private readonly ILogger<WeChatWorkService> _logger;
        private readonly IDbConnectionFactory _connectionFactory;
        private readonly IUumUserService _uumUserService;

        public WeChatWorkService(
            IOptions<WeChatWorkConfig> config,
            IConfiguration configuration,
            ILogger<WeChatWorkService> logger,
            IDbConnectionFactory connectionFactory,
            IUumUserService uumUserService)
        {
            _config = config.Value;
            _configuration = configuration;
            _logger = logger;
            _connectionFactory = connectionFactory;
            _uumUserService = uumUserService;
        }

        /// <summary>
        /// 获取企业微信授权URL
        /// </summary>
        public Task<WeChatWorkAuthUrlResponse> GetAuthUrlAsync(string? redirectUri = null, string? state = null)
        {
            try
            {
                // 使用配置的回调域名或传入的redirectUri
                var callbackUrl = !string.IsNullOrEmpty(redirectUri) ? redirectUri : 
                    $"{_config.CallbackDomain}/api/wechatwork/callback";

                // 生成状态参数
                var stateParam = !string.IsNullOrEmpty(state) ? state : Guid.NewGuid().ToString("N");

                // 构建授权URL
                var authUrl = OAuth2Api.GetCode(_config.CorpId, callbackUrl, stateParam, _config.AgentId);

                _logger.LogInformation("生成企业微信授权URL: {AuthUrl}", authUrl);

                return Task.FromResult(new WeChatWorkAuthUrlResponse
                {
                    AuthUrl = authUrl,
                    State = stateParam
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取企业微信授权URL失败");
                throw new InvalidOperationException("获取授权URL失败", ex);
            }
        }

        /// <summary>
        /// 通过授权码获取用户信息
        /// </summary>
        public async Task<WeChatWorkUserInfo?> GetUserInfoByCodeAsync(string code)
        {
            try
            {
                _logger.LogInformation("开始通过授权码获取用户信息: {Code}", code);

                // 获取Access Token
                var accessToken = await AccessTokenContainer.GetTokenAsync(_config.CorpId, _config.CorpSecret);
                if (string.IsNullOrEmpty(accessToken))
                {
                    _logger.LogError("获取Access Token失败");
                    return null;
                }

                // 通过code获取用户ID
                var userResult = OAuth2Api.GetUserId(accessToken, code);
                if (userResult == null || string.IsNullOrEmpty(userResult.UserId))
                {
                    _logger.LogError("通过授权码获取用户ID失败: {Code}", code);
                    return null;
                }

                _logger.LogInformation("获取到用户ID: {UserId}", userResult.UserId);

                // 获取用户详细信息
                var userInfo = MailListApi.GetMember(accessToken, userResult.UserId);
                if (userInfo == null)
                {
                    _logger.LogError("获取用户详细信息失败: {UserId}", userResult.UserId);
                    return null;
                }

                var result = new WeChatWorkUserInfo
                {
                    UserId = userInfo.userid ?? string.Empty,
                    Name = userInfo.name ?? string.Empty,
                    Department = userInfo.department?.Select(d => (int)d).ToArray() ?? Array.Empty<int>(),
                    Position = userInfo.position ?? string.Empty,
                    Mobile = userInfo.mobile ?? string.Empty,
                    Email = userInfo.email ?? string.Empty,
                    Avatar = userInfo.avatar ?? string.Empty,
                    Gender = userInfo.gender.ToString() ?? string.Empty,
                    Status = userInfo.status,
                    Enable = userInfo.enable
                };

                _logger.LogInformation("成功获取用户信息: {UserId} - {Name}", result.UserId, result.Name);
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "通过授权码获取用户信息失败: {Code}", code);
                return null;
            }
        }

        /// <summary>
        /// 企业微信登录
        /// </summary>
        public async Task<WeChatWorkLoginResponse> LoginAsync(string code, string? state = null)
        {
            try
            {
                _logger.LogInformation("开始企业微信登录: {Code}, State: {State}", code, state);

                // 获取用户信息
                var userInfo = await GetUserInfoByCodeAsync(code);
                if (userInfo == null)
                {
                    return new WeChatWorkLoginResponse
                    {
                        Success = false,
                        Message = "获取用户信息失败，请重试"
                    };
                }

                // 验证用户是否有效
                var isValid = await ValidateUserAsync(userInfo.UserId);
                if (!isValid)
                {
                    return new WeChatWorkLoginResponse
                    {
                        Success = false,
                        Message = "用户无权限访问系统"
                    };
                }

                // 生成JWT Token
                var token = GenerateJwtToken(userInfo);
                var expiresAt = DateTime.UtcNow.AddHours(24); // 24小时过期

                _logger.LogInformation("企业微信登录成功: {UserId} - {Name}", userInfo.UserId, userInfo.Name);

                return new WeChatWorkLoginResponse
                {
                    Success = true,
                    Message = "登录成功",
                    Token = token,
                    UserInfo = userInfo,
                    ExpiresAt = expiresAt
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "企业微信登录失败: {Code}", code);
                return new WeChatWorkLoginResponse
                {
                    Success = false,
                    Message = "登录失败，请重试"
                };
            }
        }

        /// <summary>
        /// 验证企业微信用户是否有效
        /// </summary>
        public Task<bool> ValidateUserAsync(string userId)
        {
            try
            {
                // 这里可以根据实际业务需求验证用户权限
                // 例如：检查用户是否在允许的部门、是否有特定角色等
                
                // 基本验证：用户ID不为空且状态正常
                if (string.IsNullOrEmpty(userId))
                {
                    return Task.FromResult(false);
                }

                // 可以在这里添加更多的业务验证逻辑
                // 例如：查询数据库验证用户权限、检查用户状态等
                
                _logger.LogInformation("用户验证通过: {UserId}", userId);
                return Task.FromResult(true);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "验证用户失败: {UserId}", userId);
                return Task.FromResult(false);
            }
        }

        /// <summary>
        /// 生成JWT Token
        /// </summary>
        public string GenerateJwtToken(WeChatWorkUserInfo userInfo)
        {
            try
            {
                // 使用与普通登录相同的JWT配置，确保token能被正确验证
                var secretKey = _configuration["Jwt:Key"] ?? "your-super-secret-jwt-key-that-is-at-least-32-characters-long";
                var issuer = _configuration["Jwt:Issuer"] ?? "Lzfy_Refund_Service";
                var audience = _configuration["Jwt:Audience"] ?? "Lzfy_Refund_Service_Users";

                var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
                var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                var claims = new[]
                {
                    new Claim(ClaimTypes.NameIdentifier, userInfo.UserId),
                    new Claim(ClaimTypes.Name, userInfo.Name),
                    new Claim(ClaimTypes.MobilePhone, userInfo.Mobile),
                    new Claim(ClaimTypes.Email, userInfo.Email),
                    new Claim("position", userInfo.Position),
                    new Claim("avatar", userInfo.Avatar),
                    new Claim("login_type", "wechat_work"),
                    new Claim("departments", string.Join(",", userInfo.Department))
                };

                var token = new JwtSecurityToken(
                    issuer: issuer,
                    audience: audience,
                    claims: claims,
                    expires: DateTime.UtcNow.AddHours(24),
                    signingCredentials: credentials
                );

                var tokenString = new JwtSecurityTokenHandler().WriteToken(token);
                _logger.LogInformation("为用户生成JWT Token: {UserId}", userInfo.UserId);
                
                return tokenString;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "生成JWT Token失败: {UserId}", userInfo.UserId);
                throw new InvalidOperationException("生成Token失败", ex);
            }
        }

        /// <summary>
        /// 通过企业微信用户ID查询用户名
        /// </summary>
        public async Task<WeChatWorkUsernameResponse> GetUsernameByWxUserIdAsync(string wxUserId)
        {
            try
            {
                _logger.LogInformation("开始通过企业微信用户ID查询用户名: {WxUserId}", wxUserId);

                using var connection = _connectionFactory.CreateConnection();
                
                var sql = @"
                    SELECT t1.LoginID AS username,
                           t1.UserName AS fullName,
                           t1.WxUserId AS WxUserId,
                           t1.Mobile,
                           t1.Position,
                           t1.MainDeps,
                           t1.IsDeleted,
                           t1.IsFrozen,
                           t1.StateID
                    FROM ioffice_reader.ioffice_dev.dbo.priUser t1
                    WHERE t1.IsDeleted = 0
                          AND t1.IsFrozen = 0
                          AND t1.StateID = 23
                          AND t1.WxUserId = @WxUserId";

                var result = await connection.QueryFirstOrDefaultAsync(sql, new { WxUserId = wxUserId });

                if (result == null)
                {
                    _logger.LogWarning("未找到企业微信用户ID对应的用户: {WxUserId}", wxUserId);
                    return new WeChatWorkUsernameResponse
                    {
                        Success = false,
                        Message = "未找到对应的用户信息"
                    };
                }
                _logger.LogInformation("成功查询到用户名: {WxUserId}", wxUserId);
                //_logger.LogInformation("成功查询到用户名: {Username}", result.username);

                return new WeChatWorkUsernameResponse
                {
                    Success = true,
                    Username = result.username,
                    FullName = result.fullName,
                    Mobile = result.Mobile,
                    Position = result.Position,
                    MainDeps = result.MainDeps,
                    Message = "查询成功"
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "通过企业微信用户ID查询用户名失败: {WxUserId}", wxUserId);
                return new WeChatWorkUsernameResponse
                {
                    Success = false,
                    Message = $"查询失败: {ex.Message}"
                };
            }
        }

        /// <summary>
        /// 通过用户名获取用户详细信息
        /// </summary>
        public async Task<WeChatWorkUserDetailResponse> GetUserDetailByUsernameAsync(string username)
        {
            try
            {
                _logger.LogInformation("开始通过用户名获取用户详细信息: {Username}", username);

                // 通过UumUserService获取HIS数据库中的用户信息
                var uumUser = await _uumUserService.GetUserByUserNameAsync(username);
                
                if (uumUser == null)
                {
                    _logger.LogWarning("在HIS数据库中未找到用户: {Username}", username);
                    return new WeChatWorkUserDetailResponse
                    {
                        Success = false,
                        Message = "在HIS数据库中未找到用户信息"
                    };
                }

                // 获取用户电话
                var userPhone = await _uumUserService.GetUserPhoneAsync(username);

                _logger.LogInformation("成功获取用户详细信息: {Username}, 全名: {FullName}", username, uumUser.Data?.PeopleName);

                return new WeChatWorkUserDetailResponse
                {
                    Success = true,
                    Username = username,
                    FullName = uumUser.Data?.PeopleName,
                    UserPhone = userPhone.UserPhone ?? "",
                    Id = uumUser.Data?.Id ?? 0,
                    Message = "查询成功"
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "通过用户名获取用户详细信息失败: {Username}", username);
                return new WeChatWorkUserDetailResponse
                {
                    Success = false,
                    Message = $"查询失败: {ex.Message}"
                };
            }
        }

        /// <summary>
        /// 发送企业微信消息
        /// </summary>
        public async Task<WeChatWorkMessageResponse> SendMessageAsync(WeChatWorkMessageRequest request)
        {
            try
            {
                _logger.LogInformation("开始发送企业微信消息，用户ID: {UserId}, 消息类型: {MessageType}", request.UserId, request.MessageType);

                // 根据消息类型调用相应的发送方法
                return request.MessageType.ToLower() switch
                {
                    "text" => await SendTextMessageAsync(request.UserId, request.Content),
                    "textcard" => await SendTextCardMessageAsync(request.UserId, request.Title ?? "通知", request.Description ?? request.Content, request.Url ?? "", request.BtnTxt ?? "详情"),
                    "markdown" => await SendMarkdownMessageAsync(request.UserId, request.Content),
                    _ => new WeChatWorkMessageResponse
                    {
                        Success = false,
                        Message = $"不支持的消息类型: {request.MessageType}"
                    }
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "发送企业微信消息失败，用户ID: {UserId}", request.UserId);
                return new WeChatWorkMessageResponse
                {
                    Success = false,
                    Message = $"发送消息失败: {ex.Message}"
                };
            }
        }

        /// <summary>
        /// 获取企业微信Access Token
        /// </summary>
        public async Task<string?> GetAccessTokenAsync()
        {
            try
            {
                _logger.LogInformation("开始获取企业微信Access Token");

                // 使用HttpClient调用企业微信API获取Access Token
                using var httpClient = new HttpClient();
                var url = $"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={_config.CorpId}&corpsecret={_config.CorpSecret}";
                
                var response = await httpClient.GetStringAsync(url);
                var tokenResponse = System.Text.Json.JsonSerializer.Deserialize<WeChatWorkAccessTokenResponse>(response);

                if (tokenResponse?.errcode == 0 && !string.IsNullOrEmpty(tokenResponse.access_token))
                {
                    _logger.LogInformation("成功获取企业微信Access Token，过期时间：{ExpiresIn}秒", tokenResponse.expires_in);
                    return tokenResponse.access_token;
                }
                else
                {
                    _logger.LogError("获取企业微信Access Token失败，错误码：{ErrorCode}，错误信息：{ErrorMessage}", tokenResponse?.errcode, tokenResponse?.errmsg);
                    return null;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取企业微信Access Token异常");
                return null;
            }
        }

        /// <summary>
        /// 发送文本消息
        /// </summary>
        public async Task<WeChatWorkMessageResponse> SendTextMessageAsync(string userId, string content)
        {
            try
            {
                _logger.LogInformation("开始发送文本消息，用户ID: {UserId}", userId);

                var accessToken = await GetAccessTokenAsync();
                if (string.IsNullOrEmpty(accessToken))
                {
                    return new WeChatWorkMessageResponse
                    {
                        Success = false,
                        Message = "获取Access Token失败"
                    };
                }

                var message = new WeChatWorkTextMessage
                {
                    touser = userId,
                    agentid = _config.AgentId,
                    text = new WeChatWorkTextContent { content = content }
                };

                return await SendMessageToWeChatApiAsync(accessToken, message);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "发送文本消息失败，用户ID: {UserId}", userId);
                return new WeChatWorkMessageResponse
                {
                    Success = false,
                    Message = $"发送文本消息失败: {ex.Message}"
                };
            }
        }

        /// <summary>
        /// 发送文本卡片消息
        /// </summary>
        public async Task<WeChatWorkMessageResponse> SendTextCardMessageAsync(string userId, string title, string description, string url, string btnTxt = "详情")
        {
            try
            {
                _logger.LogInformation("开始发送文本卡片消息，用户ID: {UserId}, 标题: {Title}", userId, title);

                var accessToken = await GetAccessTokenAsync();
                if (string.IsNullOrEmpty(accessToken))
                {
                    return new WeChatWorkMessageResponse
                    {
                        Success = false,
                        Message = "获取Access Token失败"
                    };
                }

                var message = new WeChatWorkTextCardMessage
                {
                    touser = userId,
                    agentid = _config.AgentId,
                    textcard = new WeChatWorkTextCardContent
                    {
                        title = title,
                        description = description,
                        url = url,
                        btntxt = btnTxt
                    }
                };

                return await SendMessageToWeChatApiAsync(accessToken, message);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "发送文本卡片消息失败，用户ID: {UserId}", userId);
                return new WeChatWorkMessageResponse
                {
                    Success = false,
                    Message = $"发送文本卡片消息失败: {ex.Message}"
                };
            }
        }

        /// <summary>
        /// 发送Markdown消息
        /// </summary>
        public async Task<WeChatWorkMessageResponse> SendMarkdownMessageAsync(string userId, string content)
        {
            try
            {
                _logger.LogInformation("开始发送Markdown消息，用户ID: {UserId}", userId);

                var accessToken = await GetAccessTokenAsync();
                if (string.IsNullOrEmpty(accessToken))
                {
                    return new WeChatWorkMessageResponse
                    {
                        Success = false,
                        Message = "获取Access Token失败"
                    };
                }

                var message = new WeChatWorkMarkdownMessage
                {
                    touser = userId,
                    agentid = _config.AgentId,
                    markdown = new WeChatWorkMarkdownContent { content = content }
                };

                return await SendMessageToWeChatApiAsync(accessToken, message);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "发送Markdown消息失败，用户ID: {UserId}", userId);
                return new WeChatWorkMessageResponse
                {
                    Success = false,
                    Message = $"发送Markdown消息失败: {ex.Message}"
                };
            }
        }

        /// <summary>
        /// 发送消息到企业微信API
        /// </summary>
        private async Task<WeChatWorkMessageResponse> SendMessageToWeChatApiAsync<T>(string accessToken, T message)
        {
            try
            {
                using var httpClient = new HttpClient();
                var url = $"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={accessToken}";
                
                var jsonContent = System.Text.Json.JsonSerializer.Serialize(message, new System.Text.Json.JsonSerializerOptions
                {
                    PropertyNamingPolicy = null,
                    WriteIndented = false
                });
                
                var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
                var response = await httpClient.PostAsync(url, content);
                var responseContent = await response.Content.ReadAsStringAsync();
                
                var apiResponse = System.Text.Json.JsonSerializer.Deserialize<WeChatWorkSendMessageApiResponse>(responseContent);
                
                if (apiResponse?.errcode == 0)
                {
                    _logger.LogInformation("企业微信消息发送成功，消息ID: {MessageId}", apiResponse.msgid);
                    return new WeChatWorkMessageResponse
                    {
                        Success = true,
                        Message = "消息发送成功",
                        MessageId = apiResponse.msgid
                    };
                }
                else
                {
                    _logger.LogWarning("企业微信消息发送失败，错误码: {ErrorCode}, 错误信息: {ErrorMessage}", apiResponse?.errcode, apiResponse?.errmsg);
                    return new WeChatWorkMessageResponse
                    {
                        Success = false,
                        Message = "消息发送失败",
                        ErrorCode = apiResponse?.errcode,
                        ErrorMessage = apiResponse?.errmsg
                    };
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "调用企业微信API发送消息异常");
                return new WeChatWorkMessageResponse
                {
                    Success = false,
                    Message = $"发送消息异常: {ex.Message}"
                };
            }
        }
    }
}